package com.bookocean.domain.service.impl;

import com.bookocean.application.exception.BusinessException;
import com.bookocean.application.exception.WeChatErrorCodeEnum;
import com.bookocean.controller.dto.NovelDto;
import com.bookocean.controller.dto.NovelChapterDto;
import com.bookocean.controller.dto.NovelParticipantDto;
import com.bookocean.domain.constant.NovelStatus;
import com.bookocean.domain.repository.NovelRepository;
import com.bookocean.domain.service.NovelDomainService;
import com.bookocean.domain.utils.UserContextHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 小说领域服务实现类
 * 
 * @author BookOcean
 * @since 2024-01-01
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NovelDomainServiceImpl implements NovelDomainService {

    private final NovelRepository novelRepository;
    
    private static final int MIN_PARTICIPANTS_FOR_MULTI = 3;

    @Override
    @Transactional
    public NovelDto createNovel(NovelDto novelDto) {
        // 设置创建者信息
        Long currentUserId = UserContextHolder.getUserId();
        novelDto.setCreatorId(currentUserId);
        novelDto.setCreateTime(LocalDateTime.now());
        novelDto.setUpdateTime(LocalDateTime.now());
        
        // 根据创作类型设置初始状态
        if (novelDto.getCreationType() == 1) {
            // 单人创作，直接进入进行中状态
            novelDto.setStatus(NovelStatus.ONGOING);
        } else {
            // 多人创作，初始为招募中状态
            novelDto.setStatus(NovelStatus.RECRUITING);
        }
        
        // 初始化统计数据
        novelDto.setCurrentChapterCount(0);
        novelDto.setLikeCount(0);
        novelDto.setCommentCount(0);
        novelDto.setFavoriteCount(0);
        
        // 创建小说
        NovelDto createdNovel = novelRepository.createNovel(novelDto);
        
        // 添加创建者为参与者
        NovelParticipantDto creatorParticipant = new NovelParticipantDto();
        creatorParticipant.setNovelId(createdNovel.getId());
        creatorParticipant.setUserId(currentUserId);
        creatorParticipant.setParticipantOrder(1);
        creatorParticipant.setIsCreator(true);
        creatorParticipant.setChapterCount(0);
        creatorParticipant.setJoinTime(LocalDateTime.now());
        
        novelRepository.addParticipant(creatorParticipant);
        
        log.info("创建小说成功，小说ID: {}, 创建者ID: {}", createdNovel.getId(), currentUserId);
        return createdNovel;
    }

    @Override
    public NovelDto getNovelById(Long novelId) {
        return novelRepository.getNovelById(novelId);
    }

    @Override
    public NovelDto getEnhancedNovelById(Long novelId, Long userId) {
        return novelRepository.getEnhancedNovelById(novelId, userId);
    }

    @Override
    @Transactional
    public NovelDto updateNovel(NovelDto novelDto) {
        NovelDto existingNovel = novelRepository.getNovelById(novelDto.getId());
        if (existingNovel == null) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_NOVEL_ERROR, "小说不存在");
        }

        Long currentUserId = UserContextHolder.getUserId();
        if (!existingNovel.getCreatorId().equals(currentUserId)) {
            throw new BusinessException(WeChatErrorCodeEnum.UPDATE_NOVEL_ERROR, "只有创建者可以修改小说信息");
        }
        
        novelDto.setUpdateTime(LocalDateTime.now());
        return novelRepository.updateNovel(novelDto);
    }

    @Override
    @Transactional
    public NovelDto completeNovel(Long novelId, Long userId) {
        NovelDto novel = novelRepository.getNovelById(novelId);
        if (novel == null) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_NOVEL_ERROR, "小说不存在");
        }
        
        // 检查权限：创建者或参与者都可以完结
        if (!novel.getCreatorId().equals(userId) && !novelRepository.isParticipant(novelId, userId)) {
            throw new BusinessException(WeChatErrorCodeEnum.UPDATE_NOVEL_ERROR, "只有参与者可以完结小说");
        }
        
        if (novel.getStatus() == NovelStatus.COMPLETED) {
            throw new BusinessException(WeChatErrorCodeEnum.UPDATE_NOVEL_ERROR, "小说已完结");
        }
        
        // 多人创作需要检查是否有完结投票且投票通过
        if (novel.getCreationType() == 2) {
            // 这里可以添加额外的多人创作完结检查逻辑
            // 由于投票逻辑已经在NovelCompleteVoteService中处理，
            // 这里主要是更新小说状态
        }
        
        novel.setStatus(NovelStatus.COMPLETED);
        novel.setUpdateTime(LocalDateTime.now());
        
        return novelRepository.updateNovel(novel);
    }

    @Override
    public List<NovelDto> getUserParticipatedNovels(Long userId, Integer page, Integer pageSize) {
        return novelRepository.getUserParticipatedNovels(userId, page, pageSize);
    }

    @Override
    public List<NovelDto> getRecruitingNovels(Integer page, Integer pageSize) {
        return novelRepository.getRecruitingNovels(page, pageSize);
    }

    @Override
    public List<NovelDto> getCompletedNovels(Integer page, Integer pageSize) {
        return novelRepository.getCompletedNovels(page, pageSize);
    }

    @Override
    @Transactional
    public NovelParticipantDto joinNovel(Long novelId, Long userId) {
        NovelDto novel = novelRepository.getNovelById(novelId);
        if (novel == null) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_NOVEL_ERROR, "小说不存在");
        }
        
        if (novel.getStatus() != NovelStatus.RECRUITING) {
            throw new BusinessException(WeChatErrorCodeEnum.ADD_PARTICIPANT_ERROR, "该小说不在招募状态");
        }
        
        if (novelRepository.isParticipant(novelId, userId)) {
            throw new BusinessException(WeChatErrorCodeEnum.ADD_PARTICIPANT_ERROR, "您已经是该小说的参与者");
        }
        
        // 获取当前参与者数量
        List<NovelParticipantDto> participants = novelRepository.getNovelParticipants(novelId);
        
        // 创建新参与者
        NovelParticipantDto participant = new NovelParticipantDto();
        participant.setNovelId(novelId);
        participant.setUserId(userId);
        participant.setParticipantOrder(participants.size() + 1);
        participant.setIsCreator(false);
        participant.setChapterCount(0);
        participant.setJoinTime(LocalDateTime.now());
        
        NovelParticipantDto addedParticipant = novelRepository.addParticipant(participant);
        
        // 检查是否达到最少参与人数，如果是多人创作且达到最少人数，则更新状态为进行中
        if (novel.getCreationType() == 2 && participants.size() + 1 >= MIN_PARTICIPANTS_FOR_MULTI) {
            novel.setStatus(NovelStatus.ONGOING);
            novel.setUpdateTime(LocalDateTime.now());
            novelRepository.updateNovel(novel);
        }
        
        log.info("用户加入小说成功，小说ID: {}, 用户ID: {}", novelId, userId);
        return addedParticipant;
    }

    @Override
    public List<NovelParticipantDto> getNovelParticipants(Long novelId) {
        return novelRepository.getNovelParticipants(novelId);
    }

    @Override
    @Transactional
    public NovelChapterDto writeChapter(NovelChapterDto chapterDto) {
        Long novelId = chapterDto.getNovelId();
        Long authorId = chapterDto.getAuthorId();
        
        // 检查小说是否存在
        NovelDto novel = novelRepository.getNovelById(novelId);
        if (novel == null) {
            throw new BusinessException(WeChatErrorCodeEnum.GET_NOVEL_ERROR, "小说不存在");
        }
        
        // 检查小说状态
        if (novel.getStatus() != NovelStatus.ONGOING) {
            throw new BusinessException(WeChatErrorCodeEnum.ADD_CHAPTER_ERROR, "该小说不在进行中状态，无法写作");
        }
        
        // 检查是否为参与者
        if (!novelRepository.isParticipant(novelId, authorId)) {
            throw new BusinessException(WeChatErrorCodeEnum.ADD_CHAPTER_ERROR, "您不是该小说的参与者");
        }
        
        // 多人创作额外检查
        if (novel.getCreationType() == 2) {
            // 检查是否今日已写过章节
            if (novelRepository.hasWrittenTodayChapter(novelId, authorId)) {
                throw new BusinessException(WeChatErrorCodeEnum.ADD_CHAPTER_ERROR, "您今日已写过章节，请明日再来");
            }
            
            // 检查是否轮到该用户写作（可选实现，这里简化处理）
            // Long nextWriterId = novelRepository.getNextWriterUserId(novelId);
            // if (!nextWriterId.equals(authorId)) {
            //     throw new BusinessException("暂未轮到您写作");
            // }
        }
        
        // 设置章节信息
        chapterDto.setChapterNumber(novelRepository.getNextChapterNumber(novelId));
        chapterDto.setCreateTime(LocalDateTime.now());
        chapterDto.setLikeCount(0);
        chapterDto.setCommentCount(0);
        
        // 添加章节
        NovelChapterDto addedChapter = novelRepository.addChapter(chapterDto);
        
        // 更新小说的章节数和更新时间
        novel.setCurrentChapterCount(novel.getCurrentChapterCount() + 1);
        novel.setUpdateTime(LocalDateTime.now());
        
        // 检查是否达到目标章节数，如果是则自动完结
        if (novel.getTargetChapterCount() != null && 
            novel.getCurrentChapterCount() >= novel.getTargetChapterCount()) {
            novel.setStatus(NovelStatus.COMPLETED);
        }
        
        novelRepository.updateNovel(novel);
        
        log.info("写作章节成功，小说ID: {}, 章节ID: {}, 作者ID: {}", 
                novelId, addedChapter.getId(), authorId);
        
        return addedChapter;
    }

    @Override
    public List<NovelChapterDto> getNovelChapters(Long novelId) {
        return novelRepository.getNovelChapters(novelId);
    }

    @Override
    public NovelChapterDto getEnhancedChapterById(Long chapterId, Long userId) {
        return novelRepository.getEnhancedChapterById(chapterId, userId);
    }

    @Override
    public boolean canWriteNextChapter(Long novelId, Long userId) {
        NovelDto novel = novelRepository.getNovelById(novelId);
        if (novel == null || novel.getStatus() != NovelStatus.ONGOING) {
            return false;
        }
        
        if (!novelRepository.isParticipant(novelId, userId)) {
            return false;
        }
        
        // 多人创作需要检查是否今日已写过
        if (novel.getCreationType() == 2) {
            return !novelRepository.hasWrittenTodayChapter(novelId, userId);
        }
        
        return true;
    }
}
